import org.apache.commons.io.FileUtils;
import utils.CollectionUtils;
import utils.ListSomeLevelDirsFiles;
import utils.MD5Utils;
import utils.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 将静态页面中包含的script,和css文件,生成md5版本后缀
public class ReplaceHtmlPage {

    public static final String UTF_8 = "utf-8";

    private File rootDir;
    private File dataDir;
    private File currentDir;

    public void setRootDir(File rootDir) {
        this.rootDir = rootDir;
    }

    public void setDataDir(File dataDir) {
        this.dataDir = dataDir;
    }

    public static void main(String[] args) throws IOException {

        String file = ReplaceHtmlPage.class.getClassLoader().getResource("testdata").getFile();

        File dir = new File(file);
        File rootdir = dir.getParentFile();

        ReplaceHtmlPage replaceHtmlPage = new ReplaceHtmlPage();
        replaceHtmlPage.setRootDir(rootdir);
        replaceHtmlPage.setDataDir(dir);
        replaceHtmlPage.run();

    }

    public void run() throws IOException {
        ListSomeLevelDirsFiles files = ListSomeLevelDirsFiles.generateMaxLevelList(this.dataDir);
        for (File file : files) {
            if (file.getName().toLowerCase().endsWith(".html")) {
                handleFile(file);
            }
        }
    }

    private void handleFile(File file) throws IOException {
        System.out.println(file.getAbsolutePath());

        this.currentDir = file.getParentFile();

        List<String> lines = FileUtils.readLines(file, UTF_8);
        lines = CollectionUtils.map(lines, e -> {
            String ret = handleLine(e);
            if (!e.equals(ret)) {
                System.out.println("  " + e + " --> " + ret);
            }
            return ret;
        });
        FileUtils.writeLines(file, UTF_8, lines);
    }

    private String handleLine(String line) {

        String newline = line.trim().toLowerCase();

        if (newline.startsWith("<script") && newline.endsWith("</script>")) {
            return replaceFilePathByAttrName(line,"src");
        }else if(newline.startsWith("<link") && newline.contains("rel=\"stylesheet\"") && newline.endsWith("/>")){
            return replaceFilePathByAttrName(line,"href");
        }

        return line;
    }

    private String replaceFilePathByAttrName(String line, String attrName) {
        String regex = " " + attrName +
                "=\".*?\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(line);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String startString = " " + attrName +
                    "=\"";
            String endString = "\"";

            String indexString = matcher.group();
            indexString = StringUtils.removeStartEnd(indexString, startString, endString);
            String md5filepath = generateMD5(indexString);
            matcher.appendReplacement(sb,
                    Matcher.quoteReplacement(startString + md5filepath + endString));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    private String generateMD5(String filePath) {
        try {
            if (filePath.contains("?")) {
                filePath = filePath.substring(0, filePath.indexOf("?"));
            }

            File file = null;
            if(filePath.startsWith("/")) {
                file = new File(rootDir, filePath);
            }else {
                file = new File(currentDir, filePath);
            }

            String md5 = MD5Utils.getMD5(FileUtils.readFileToString(file, UTF_8));

            return filePath + "?_v=" + md5;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
